package com.gylang.springmini.factory;

import com.gylang.springmini.exception.BeansException;
import org.springframework.lang.Nullable;

import java.lang.annotation.Annotation;
import java.util.Map;

/**
 * @author gylang
 * data 2021/11/12
 */
public interface ListableBeanFactory {


    /**
     * 获取特定类型的bean名称
     *
     * @param type bean的类型
     * @return bean的名称列表
     */
    String[] getBeanNamesForType(@Nullable Class<?> type);

    /**
     * 获取特定类型的bean名称
     *
     * @param type                 bean的类型
     * @param includeNonSingletons 是否包含非单例
     * @param allowEagerInit       是否允许为早期对象(未执行完初始化的对象)
     * @return
     */
    String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

    /**
     * 获取特定类型的beanMap
     *
     * @param type bean的类型
     * @return 获取特定类型的bean集合map
     * @throws BeansException 当获取的对象不存在
     */
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

    /**
     * 获取特定类型的beanMap
     *
     * @param type                 bean的类型
     * @param includeNonSingletons 是否包含非单例
     * @param allowEagerInit       是否允许为早期对象(未执行完初始化的对象)
     * @return @throws BeansException 当获取的对象不存在
     */
    <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
            throws BeansException;


    /**
     * 查找使用提供的Annotation类型注释的 bean 的所有名称，而不创建相应的 bean 实例。
     * 请注意，此方法考虑由 FactoryBeans 创建的对象，这意味着 FactoryBeans 将被初始化以确定它们的对象类型。
     *
     * @param annotationType – 要查找的注释类型（在指定 bean 的类、接口或工厂方法级别）
     * @return 所有匹配 bean 的名称
     */
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

    /**
     * 查找使用提供的Annotation类型进行注释的所有 bean，返回带有相应 bean 实例的 bean 名称的 Map。
     * 请注意，此方法考虑由 FactoryBeans 创建的对象，这意味着 FactoryBeans 将被初始化以确定它们的对
     *
     * @param annotationType 要查找的注释类型（在指定 bean 的类、接口或工厂方法级别）
     * @return 所有匹配 bean 的名称
     * @throws BeansException bean不存在
     * @since 3.0
     */
    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;



}
